前言
有了上一篇的内容,相信读者你已经对 Promise 的主体实现已经有了一定掌握。本文将是这个系列的中篇内容,本篇将对 Promise 规范里的对象方法和静态方法进行内容,最后在下篇针对实际面试和使用场景进行讲解。
1、实例方法
then、catch 以及 finally 方法都是 Promise.prototype 里的方法,都属于实例方法。上篇中我们以及实现了前两个,接下来我们给出 finally 方法的实现。
1.1、finally 实现
finally 是 Promise 实例的一个方法,在上篇内容中有提到,我们现在先补上这部分内容。首先,我们来看一下 finally 。
- finally 会在 onfulfilled/onrejected 回调执行完之后被执行到
- finally 会返回一个新的 promise 对象,并且这个对象的状态为 fulfilled,fulfilledValue 为 undefined
那么,finally 代码实现为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| * * @param {*} onfinally * @returns */ MyPromise.prototype.finally = function(onfinally){ return new MyPromise((resolve, reject) => { this._handle({ type: TYPES.FINALLY, resolve, reject, onfinally }) }) }
|
2、静态方法
Promise 的静态方法有很多,但是基本上按传入参数可以分两类,Promise 对象数组(或 iterable 类型,Array,Map,Set都属于ES6的 iterable 类型,下文中我们简化为数组类型的情形)和其他。我们先来看看归纳在 “其他” 里的方法。
2.1、resolve、reject 实现
这里的 resolve、reject 有别于上篇中 MyPromise 中的内部方法,这两个方法都接受一个参数,并得到一个 promise 对象,其 fulfilledValue/rejectedReason 就是传入参数。比较简单,我们直接上代码:
1 2 3 4 5 6 7 8 9 10 11 12
| MyPromise.resolve = function(rs) { const pro = new MyPromise(resolve => { resolve(rs) }) return pro } MyPromise.reject = function(err) { const pro = new MyPromise((resolve, reject) => { reject(err) }) return pro }
|
2.2、race 实现
传入一个 Promise 类型数组,返回一个 Promise 对象。
其中任意一个 promise 对象达到终态,则进入 onfulfilled 或 onrejected 函数。
如果入参空数组,则 pending,非数组类型入参会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| MyPromise.race = function(array){ if(!Array.isArray(array)) throw new Error('array not Array') return new MyPromise((resolve, reject)=>{ const len = array.length for (let i = 0; i < len; i++) { const p = array[i]; p.then(res=>{ resolve(res) }) .catch(err=>{ reject(err) }) } }) }
|
2.3、all 实现
传入一个 Promise 类型数组,返回一个 Promise 对象。
当所有 promise 达到 fullfilled 或 任意一个 promise 达到 rejected,则结束。
如果入参空数组,则返回一个 fullfilled 的promise,非数组类型入参会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| MyPromise.all = function(array) { if(!Array.isArray(array)) throw new Error('array not Array') return new MyPromise((resolve, reject)=>{ const ans = [] let count = 0 const len = array.length if(len === 0) resolve(ans) for (let i = 0; i < len; i++) { const p = array[i]; p.then(res=>{ ans[i] = res count++ if(count === len) resolve(ans) }) .catch(err=>{ reject(err) }) } }) }
|
2.4、allSettled 实现
传入一个 Promise 类型数组,返回一个 Promise 对象。
当所有 promise 达到 fullfilled 或 rejected,则结束。
如果入参空数组,则返回一个 fullfilled 的promise,非数组类型入参会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| MyPromise.allSettled = function(array) { if(!Array.isArray(array)) throw new Error('array not Array') return new MyPromise((resolve, reject)=>{ const ans = [] let count = 0 const len = array.length if(len === 0) resolve(ans) for (let i = 0; i < len; i++) { const p = array[i]; p.then(res=>{ ans[i] = { status: PRO_STATUS.FULFILLED, value: res } count++ if(count === len) resolve(ans) }) .catch(err=>{ ans[i] = { status: PRO_STATUS.REJECTED, reason: err } count++ if(count === len) resolve(ans) }) } }) }
|
2.5、any 实现
传入一个 Promise 类型数组,返回一个 Promise 对象。
当所有 promise 达到 rejected 或 有一个达到 fulfilled 状态,则结束。
如果入参空数组,则返回一个 rejected 的promise,非数组类型入参会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| MyPromise.any = function(array) { if(!Array.isArray(array)) throw new Error('array not Array') return new MyPromise((resolve, reject)=>{ const ans = [] let count = 0 const len = array.length if(len ===0) reject(new AggregateError('')) for (let i = 0; i < len; i++) { const p = array[i]; p.then(res=>{ resolve(res) }) .catch(err=>{ count++ if(count === len) reject(ans) }) } }) }
|
3、结语
通过本文的介绍,我们实现了所有 Promise 相关的标准 API 方法。下一节中,我们介绍一些基于 Promise 来实现一些在面试或实际业务中碰到的问题解法。